<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * User_files.php
 *
 * @author  :  Skiychan <dev@skiy.net>
 * @created :  2015/6/3
 * @modified:  
 * @version :  0.0.1
 */

require(APPPATH.'libraries/Android_Controller.php');
class User_files extends Android_Controller {

    private $_user_info;

    public function __construct() {
        parent::__construct();
        $services = array(
            "login_service",
            "user_info_service",
            "user_files_service",
            "user_policies_service"
        );
        $this->load->service($services);
        $this->_user_info = $this->login_service->get_user_info();
    }

    public function test_get() {
        echo json_encode($this->_user_info);
    }

    /**
     * 获取文档列表
     */
    public function files_get() {
        $folder_id = (int)$this->input->get('pid', true);
        if ($folder_id < 0)
            return $this->common_response(1003);

        $list = $this->user_files_service->get_list($this->_user_info['id'], $folder_id,"","creation_ts","desc");

        $folders = (array)$list['folders'];
        $folder_tmp = array();
        foreach ($folders as $key => $value) {
            $value['size'] = "0";
            $value['ext_name'] = "0";
            $folder_tmp[] = $value;
        }
        if (count($folder_tmp) > 0) {
            $folders = $folder_tmp;
        }

        $result = array_merge($folders, (array)$list['files']);
        return $this->common_response(0, '', array('data' => $result));
    }

    /**
     * 获取文件策略
     */
    public function file_policy_get() {
        $file_id = (int)$this->input->get('id',   true);
        //$type    = (int)$this->input->get("type", true); //0文件,1文件夹
        $type = 0;
        if (empty($file_id)) return
            $this->common_response(1003);

        $file = $this->user_policies_service->get_policy($this->_user_info['id'], $type, $file_id);
        if(empty($file))
            return  $this->common_response(7001);

        $file_policies = json_decode($file['data'], TRUE);
        $retArr = array(
            'read_pwd' => "",
            'life_span' => 0,
            'open_counter' => 0,
            'delete_after_expired' => 0
        );
        if (NULL !== $file_policies) {
            foreach ($file_policies as  $index => $file_policy){
                if($file_policy['des'] == 'read_pwd') {  //密码
                    $pwd = empty($file_policy['value_set']) ? '' : (string)$file_policy['value_set'];
                    if (mb_strlen($pwd) < 4) {
                        $pwd = '';
                    } else {
                        $pwd = mb_substr($pwd, 0, 4);
                    }
                    $retArr['read_pwd'] = $pwd;
                }else{ //其它参数
                    $retArr[$file_policy['des']] = (int)$file_policy['value_set'];
                }
            }
        }

        return $this->common_response(0, '', array('data' => $retArr));
    }

    /**
     * Important接口
     * ::分享文件::
     * ::更新文件夹和文件策略::
     * v2.0 不支持多文件分享
     * v2.0 不支持文件夹分享
     */
    public function file_policy_put() {
        $file_id = (int)$this->put('files');
        /*
        $file_id = trim($this->put('files'));
        $folder_id = trim($this->put('folders'));*/
        $name = trim($this->put('name')) ;

        #直接分享,不修改文件策略
        $shared = (int)$this->put("share");

        /*
        //支持文件及文件夹功能
        if (empty($file_id) && empty($folder_id))
            return $this->common_response(1003);

        $file_ids = empty($file_id) ? array() : explode(',', $file_id);
        $folder_ids = empty($folder_id) ? array() : explode(',', $folder_id);
        */
        $folder_ids = array();
        $file_ids = array($file_id);

        #如果直接分享则需要判断子孙目录的文件TRUE,如果是访问控制分享则FALSE
        $children = empty($shared) ? false : true;
        $data = $this->user_policies_service->get_data_info($this->_user_info['id'], $file_ids, $folder_ids, $children);

        #是否存在禁止文件/文件夹开关
        $ac = false;
        $result = $denied_ids = array();
        foreach ($data as $keys => $values) {
            foreach ($values as $key => $value) {
                if ($value['access_denied'] == 1) {
                    if (!$ac) $ac = true; //如果ac本来是false则true
                    $denied_ids[$keys][] = $value['id'];
                }
                $value['uid'] = $this->_user_info['id'];
                $result[$keys][] = $value;
            }
        }
        //无文件
        if (empty($result))
            return $this->common_response(7103);

        //存在不可分享的文件
        //if ($ac) return $this->common_response(7007);
        if ($ac)
            return $this->common_response(7007, '', array('data' => implode(',', $denied_ids['files'])));

        if (! $shared) {
            $life_span = $this->put('life_span');
            if (! empty($life_span)) {
                if ((int)$life_span < time())
                    return $this->common_response(1020);
            }

            $max_open_counter = 9999999;  //最大可查阅次数
            #限制最大查阅次数
            $open_counter = (int)$this->put('open_counter');
            if ($open_counter > $max_open_counter)
                $open_counter = $max_open_counter;

            $pwd = (string)trim($this->put('read_pwd'));
            if (mb_strlen($pwd) < 4) {
                $pwd = '';
            } else {
                $pwd = mb_substr($pwd, 0, 4);
            }
            $invar['read_pwd'] = $pwd;
            $invar['life_span'] = (int)$life_span;
            $invar['open_counter'] = (int)$open_counter;
            $invar['delete_after_expired'] = (int)$this->put('delete_after_expired');

            #组合策略
            $arr_avgs = array();
            foreach ($invar as $k => $v) {
                $arr_avgs[] = array('des' => $k, 'value_set' => $v);
            }

            if (isset($result['files'])) {
                foreach ($result['files'] as $v) {
                    $this->user_policies_service->add_policies($v, 1, $arr_avgs);
                }
            }
            if (isset($result['folders'])) {
                foreach ($result['folders'] as $v) {
                    $this->user_policies_service->add_policies($v, 2, $arr_avgs);
                }
            }
        }

        $this->load->service('share_service');
        $list_str = $this->share_service->create_file_str($file_ids, $folder_ids);
        $list_md5 = md5($list_str);  //连接符md5加密
        $res = $this->share_service->check_share_code($list_md5);
        $list_hash = Common::time33($list_md5);

        #分享列表标题
        $name = ('' === $name) ? $this->lang->line('share_name') : $name;

        #已存在分享
        if (! empty($res)) {
            unset($res['id']);
            $res['name'] = $name;
            $res['share_link'] = site_url('/s/'.$res['share_code']);
            return $this->common_response(0, '', array('data' => $res));
        }

        #生成分享码
        $share_codes = $this->share_service->short_code($list_str.time(), FALSE);
        $share_code = $share_codes[0];
        $share = array(
            "name" => $name, //$list_name
            "share_code" => $share_code,
            'share_code_hash' => Common::time33($share_code),
            'list_md5' => $list_md5,
            'list_md5_hash' => $list_hash,
            'password' => '',
            'uid' => $this->_user_info['id'],
            "creation_ts" => time()
        );

        $slist = array();
        if (! empty($file_ids)) {
            foreach ($file_ids as $val) {
                $slist[] = array('ctype' => 1, 'c_uuid' => $val);
            }
        }
        if (! empty($folder_ids)) {
            foreach ($folder_ids as $val) {
                $slist[] = array('ctype' => 2, 'c_uuid' => $val);
            }
        }

        //添加分享
        $flag = $this->share_service->add($share, $slist);
        if (empty($flag))
            return $this->common_response(1017);

        if (! empty($file_ids))
            $this->share_service->update_shared_batch($this->_user_info['id'], $file_ids);

        if (! empty($folder_ids))
            $this->share_service->update_files_shared($this->_user_info['id'], $folder_ids);

        $cb = array(
            'name' => $name,
            'password' => '',
            'share_code' => $share_code,
            'share_link' => site_url('/s/'.$share_code)
        );
        return $this->common_response(0, '', array('data' => $cb));
    }

    /**
     * 获取文件受限状态
     * v1.0支持多文件及多文件夹权限检测
     */
    public function access_denied_get() {

        /*
       //v1.0
        $file_id = trim($this->input->get('files'));
        $folder_id = trim($this->input->get('folders'));

        if (empty($file_id) && empty($folder_id)) return $this->common_response(1003);

        $file_ids = empty($file_id) ? '' : explode(',', $file_id);
        $folder_ids = empty($folder_id) ? '' : explode(',', $folder_id);
        */
        $file_id = (int)$this->input->get('files');
        if (empty($file_id))
            return $this->common_response(1003);

        $file_ids = array($file_id);
        $folder_ids = array(); //文件夹功能关闭

        $children = false;
        $data = $this->user_policies_service->get_data_info($this->_user_info['id'], $file_ids, $folder_ids, $children);

        //判断是否有文件
        if (empty($data['files']))
            return $this->common_response(7103);

        $ac = false;  //是否存在禁止文件/文件夹开关
        $result = $denied_ids = array();
        foreach ($data as $keys => $values) {
            foreach ($values as $key => $value) {
                if ($value['access_denied'] == 1) {
                    if (!$ac) $ac = TRUE; //如果ac本来是false则true
                    $denied_ids[$keys][] = $value['id'];
                }
                $value['uid'] = $this->_user_info['id'];
                $result[$keys][] = $value;
            }
        }
        if ($ac)
            return $this->common_response(7007, '', array('data' => implode(',', $denied_ids['files'])));

        return $this->common_response(0);
    }

    /**
     * 更新文件权限
     */
    public function access_denied_put() {
        $file_id = (int)$this->put('id');
        $denied = (int)$this->put('denied');
        //$type = (int)$this->put("type"); //0文件,1文件夹
        if (empty($file_id))
            return $this->common_response(1003);

        if (! in_array($denied, array(0,1)))
            return $this->common_response(1003);

        /**
        //隐藏文件夹功能
        $files = $folders = '';
        if ($type === 0) {
            $files = explode(",",$file_id);;
        } else {
            $folders = explode(",",$file_id);
        }
         */
        $all = false;
        $files = array($file_id);
        $folders = array();

        $edit = $this->user_files_service->update_access_denied($this->_user_info['id'], $files, $folders, $denied, $all);
        if ($edit)
            return $this->common_response(0);

        return $this->common_response($this->user_files_service);
    }

    /**
     * 获取文件轨迹
     * @param array $where 条件
     * @param string $field 字段
     */
    private function __file_trace($where=array(), $list=false, $field="id,actor,event,ts,unsafe,hidden,file_id,actor_ip,actor_city") {
        $file_id = (int)$this->input->get('id', true);
        $page = (int)$this->input->get('page', true);
        $total = (int)$this->input->get('total', true);

        if (empty($file_id))
            return $this->common_response(1003);

        $this->load->service('file_trace_service');

        //轨迹翻页
        $limit_num = empty($total) ? $this->config->item('file_trace_num') : $total;
        $limit = array($page * $limit_num, $limit_num);

        if (true === $list) {
            $dates_data = $this->file_trace_service->get_trace_list($file_id, $where, $limit);
        } else {
            $dates_data = $this->file_trace_service->get_traces($file_id, $where,"ts","desc", $field, $limit);
        }

        //如果没有轨迹则参数错误
        if (empty($dates_data['rows']))
            return $this->common_response(1018);

        return $dates_data['rows'];
    }

    /**
     * 获取指定文件的轨迹 -> 按日期分组
     */
    public function file_traces_get() {
        $where = array("hidden"=>0, "relation"=>0);

        $dates_data = $this->__file_trace($where, true);
        //$traces = $this->file_trace_service->traces_format($dates_data, 0);
        $traces = $this->file_trace_service->list_format($dates_data, 0, $this->_user_info['id']);

        return  $this->common_response(0, '', array('data' => $traces));
    }

    /**
     * 文件删除
     */
    public function files_delete() {

        /**
        //支持文件夹和文件批量删除
        $files = trim($this->delete('files'));
        $folders = trim($this->delete('folders'));
        if (empty($files) && empty($folders))
            return $this->common_response(1003);

        $files = empty($files) ? array() : explode(',', $files);
        $folders = empty($folders) ? array() : explode(',', $folders);
        */
        $folders = array();
        $file = (int)$this->delete('files');
        if (empty($file))
            $file = (int)$this->input->get_post('files');

        if (empty($file))
            return $this->common_response(1003);

        $files = array($file);
        $this->user_files_service->delete($this->_user_info['id'], $files, $folders);
        return $this->common_response(0);
    }

    /**
     * 获取单个文件下载地址 未检测
     * 未作安全过滤
     * 已启用添加检测功能的新接口，本接口停止使用
     */
    /**
    private function old_single_download_get(){
        $id = $this->get('fid');
        if(empty($id)){
            return $this->common_response(1003);
        }

        $code = $this->get('code');
        if (! empty($code)) {
            return $this->single_download2_get($code, $id);
        }

        $data = $this->user_files_service->get_all_file_info($id,array("deleted" => 0, "access_denied" =>0),array(),array("type"=>2),"uid,name,size,ext_name,source_guid","","guid,size as s_size");
        $share_uid = $data['uid'];
        $file_info = array(
            "name"=>$data['name'],
            "size"=>$data['s_size'],
            "format_size"=>Common::format_byte($data['s_size']),
            "full_name"=>$data['name'].".".$data['ext_name'],
            "ext_name"=>$data['ext_name']
        );
        if(empty($data) || empty($data['guid']))
        {
            $this->common_response(7001);
        }
        $file_guid = $data['guid'];
        $ext = ".ek";
        $file_name = $data['name']."_".$data['ext_name'].$ext;
        $link_id = Common::uniqid();
        $data = json_encode(array("guid"=>$file_guid,"name"=>rawurlencode($file_name)));

        $redis = new Redis();
        $connect = $redis->connect($this->config->item("host","redis"),$this->config->item("port","redis"),$this->config->item("timeout","redis"));
        if(!$connect)
        {
            $this->common_response(1019);
        }
        else
        {
            $this->user_files_service->update_file_info(array("id"=>$id),array("downloaded"=>1));
            //下载链接存活时间
            $download_exp = $this->config->item("download_expire_time");
            $set = $redis->setex($link_id,$download_exp,$data);
            if(!$set)
            {
                $this->common_response(1019);
            }
        }
        
        //记录轨迹
        $this->load->service('share_service');
        $single_file = array(array('id' => $id));
        Traces::trace_download_batch($single_file, Traces::EVENT_DOWNLOAD_SECURE_FILE);
        $this->share_service->update_downloaded_batch($share_uid, $single_file);
        $this->common_response(0,NULL,array("url"=>site_url("/d?id=".$link_id),"data"=>$file_info),FALSE);
    }
    */

    /**
     * 下载单个受控文件 + 检测
     */
    public function single_download_get() {
        $code = $this->get('code');
        $id = $this->get('fid');
        if(empty($id) || empty($code))
            return $this->common_response(1003);

        $this->load->service('share_page_service');
        #通过分享码取分享信息
        $share_res = $this->share_page_service->get_share_link($code);
        if (empty($share_res))
            return $this->common_response(7104);

        #取分享列表
        $share_list = $this->share_page_service->get_share_list($share_res['id']);
        if (empty($share_list))
            return $this->common_response(7014);

        $share_folders    = $share_files    = array();  //分享的文件夹或文件
        $share_folder_ids = $share_file_ids = array();  //分享的文件夹id或文件id
        foreach ($share_list as $key => $value) {
            if ($value['type'] == 2) {
                $share_folders[]    = $value;
                $share_folder_ids[] = $value['fid'];
            } else {
                $share_files[]    = $value;
                $share_file_ids[] = $value['fid'];
            }
        }

        $data = $this->user_files_service->get_all_file_info($id,array("deleted" => 0, "access_denied" =>0),array(),array("type"=>2),"uid,name,size,ext_name,source_guid,folder_id","","guid,size as s_size");

        if (empty($data) || empty($data['guid']))
            return $this->common_response(7001);


        #文件不在分享列表中
        if (! in_array($id, $share_file_ids)) {

            if (empty($data['folder_id']))
                return $this->common_response(7104);

            $in_share = false;
            $folder_info = $this->user_files_service->get_folders_path($share_res['uid'], $data['folder_id']);

            #无此文件夹
            if (empty($folder_info))
                return $this->common_response(7104);

            $path_ids = explode(',', $folder_info[0]['path']);
            #当前文件夹
            $path_ids[] = $data['folder_id'];
            foreach ($share_folder_ids as $v) {
                if (in_array($v, $path_ids)) {
                    $in_share = true;
                    break;
                }
            }


            #不在分享的文件夹中
            if (! $in_share)
                return $this->common_response(7104);
        }

        $share_uid = $data['uid'];
        $file_info = array(
            "name"=>$data['name'],
            "size"=>$data['s_size'],
            "format_size"=>Common::format_byte($data['s_size']),
            "full_name"=>$data['name'].".".$data['ext_name'],
            "ext_name"=>$data['ext_name']
        );

        $file_guid = $data['guid'];
        $ext = ".ek";
        $file_name = $data['name']."_".$data['ext_name'].$ext;
        $link_id = Common::uniqid();
        $data = json_encode(array("guid"=>$file_guid,"name"=>rawurlencode($file_name)));

        $redis = new Redis();
        $connect = $redis->connect($this->config->item("host","redis"),$this->config->item("port","redis"),$this->config->item("timeout","redis"));
        if(!$connect)
        {
            $this->common_response(1019);
        }
        else
        {
            $this->user_files_service->update_file_info(array("id"=>$id),array("downloaded"=>1));
            //下载链接存活时间
            $download_exp = $this->config->item("download_expire_time");
            $set = $redis->setex($link_id,$download_exp,$data);
            if(!$set)
            {
                $this->common_response(1019);
            }
        }

        //记录轨迹
        $this->load->service('share_service');
        $single_file = array(array('id' => $id));
        Traces::trace_download_batch($single_file, Traces::EVENT_DOWNLOAD_SECURE_FILE);
        $this->share_service->update_downloaded_batch($share_uid, $single_file);
        $this->common_response(0,NULL,array("url"=>site_url("/d?id=".$link_id),"data"=>$file_info),FALSE);
    }

    /**
     * 获取打包进度
     */
    public function pack_percent_get()
    {
        //本地调试服务器处理
        $id = $this->input->get("id",TRUE);
        if(empty($id)){
            $this->common_response(1003);
        }
        $redis = new Redis();
        $con = $redis->connect($this->config->item("host","redis"), $this->config->item("port","redis"), $this->config->item("timeout","redis"));
        if(!$con)
        {
            $this->common_response(1019);
        }
        $redis_data =  $redis->get($id);
        $data=json_decode($redis_data,true);
        if(!$data)
        {
            $this->common_response(1019);
        }
        if(isset($data['error_code']) && $data['error_code']>0)
        {
            $this->common_response($data['error_code']);
        }
        $space = $this->user_info_service->get_format_space($this->_user_info['id']);
        $this->common_response(0,NULL,array("percent"=>$data['percent'],"id"=>$id,"data"=>$data['data'],"space"=>$space),FALSE);

    }

    /**
     * iOS端截屏添加文件轨迹
     */
    public function screen_shot_post() {
        $file_id = (int)$this->post('id');

        Traces::trace_file($file_id, Traces::EVENT_SCREEN_SHOT_FILE, '', '', $this->_user_info['id']);
        return $this->common_response(0);
    }

    /**
     * 搜索
     */
    public function search_get() {
        $keyword = trim($this->get('keyword'));
        $page  = (int)$this->get('page');
        $total = (int)$this->get('total');

        if ($keyword === "") {
            return $this->common_response(1003);
        }

        $field = array('id','name','size','ext_name','folder_id');
        $result = $this->user_files_service->search($this->_user_info['id'], $keyword, $page, $total, $field);

        return $this->common_response(0, '', array('data' => $result));
    }

}